﻿module Mueller.CoffeeMonitor.Program

    open System
    open System.IO
    open System.Configuration
    open System.Windows.Forms
    open System.Threading
    open System.Diagnostics

    let domainError (sender:obj) (e:UnhandledExceptionEventArgs) =
        EventLog.WriteEntry("CoffeeMonitor", e.ExceptionObject.ToString())
        MessageBox.Show((e.ExceptionObject :?> exn).Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) |> ignore
        Application.Exit()

    let dispose (d: #IDisposable) = d.Dispose()

    [<EntryPoint; STAThread>]
    let main args =
        // ensure only one copy of the app runs at a time
        let mutable isFirstCopy = false
        use mutex = new Mutex(true, "CoffeeMonitor", &isFirstCopy)

        if isFirstCopy then
            AppDomain.CurrentDomain.UnhandledException.AddHandler(UnhandledExceptionEventHandler(domainError))
            Application.SetCompatibleTextRenderingDefault true
            Application.EnableVisualStyles()
            SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext())

            let settings = 
                let loaded = Settings.load()
                ref { loaded with Paths = loaded.Paths |> List.filter (fst >> Directory.Exists) }

            let monitor = ref (new CompileMonitor(!settings))

            let rec showForm () =
                let form = new SettingsForm(!settings)
                match form.ShowDialog() with
                | DialogResult.OK ->
                    Settings.save form.Settings
                    dispose !monitor
                    let cm = new CompileMonitor(form.Settings)
                    settings := form.Settings
                    monitor  := cm
                    Notification.init cm.CompileAll showForm
                | _ -> ()

            try
                if (!settings).Paths.Length = 0 then
                    showForm()
                    if (!settings).Paths.Length = 0 then
                        Notification.init id showForm
                else
                    Notification.init (!monitor).CompileAll showForm
                Updates.StartChecking()
                Application.Run()
            finally
                Settings.save !settings
                mutex.ReleaseMutex()
            0
        else
            MessageBox.Show("CoffeeScript Monitor is already running. Cannot run a second time.", "Already Running", MessageBoxButtons.OK, MessageBoxIcon.Error) |> ignore
            -1
